using System;
using System.Collections;
using System.Collections.Generic;
using System.Resources;
using System.IO;
using System.Drawing;
namespace ConsoleApplication3
{
    class Program
    {
        //写在前面：
        //1.这个辅助类可以帮你把任意多的任意对象都塞到一个文件里去，也能一次性的提出来
        //2.赶时间，一句try.catch都没写，自己补上
        //3.不建议将不同类型的对象打包到一个文件里。用Image就都Image，用string就都string，免得取出来后还要判断类型
        //4.增加和删除我没有写，原因是打包的资源文件本质是连续的字节流，从中间删一个文件太麻烦
        //5.增加操作可以使用非覆盖模式的打包方法强制追加（后面有说明）
        //6.删除操作建议读取所有的资源，删掉不要的然后一次性覆盖写入
        //7.再次提醒，.NET是决不允许资源名重名或者是数字首字资源名的。数字首字问题我已处理，重名问题自己看着办，最好穿进去前就丢到字典当主键
        //8.我未做文件占用检测，所以请避免一边打包一边解包。
        //9.此为静态类，给客户用的增删改小工具程序请把此类复制走
        //999.感谢您的围观！代码随便用！有麻烦还找我！
        static void Main(string[] args)
        {
            //打包
            Dictionary<string, object> dicToPack = new Dictionary<string, object>();
            dicToPack.Add("key1", Image.FromFile(@"c:\Users\Mako\Pictures\1.jpg"));
            dicToPack.Add("key2", "hello world");
            ResPacker.Pack(dicToPack);
            //解包
            Dictionary<string,object> dicRcv= ResPacker.GetAllResources();
            Console.WriteLine((string)dicRcv["key2"]);
            Console.WriteLine(dicRcv["key1"].GetType().FullName);
            Console.ReadKey();
        }
    }
    public static class ResPacker
    {
        /// <summary>
        /// 批量打包任意对象到资源文件
        /// </summary>
        /// <param name="objCollection">被打包对象的列表。键值对中键为其在资源文件中的唯一标示名。</param>
        /// <param name="targetFilePath">目标资源文件。默认参数为当前目录下的"MyRes.pck"文件。</param>
        /// <param name="overwrite">是否覆盖已存在的目标文件。默认=True</param>
        public static void Pack(IDictionary<string,object> objCollection, string targetFilePath = "MyRes.pck", bool overwrite = true)
        {
            if (overwrite)
                File.Delete(targetFilePath);
            using (ResourceWriter rw = new ResourceWriter(targetFilePath))
            {
                foreach (KeyValuePair<string, object> pair in objCollection)
                    //为了防传进来的资源名有数字开头，资源名都加了前缀_
                    rw.AddResource("_" + pair.Key, pair.Value);
                rw.Generate();
                rw.Close();
            }
        }
        /// <summary>
        /// 解包资源文件，返回所有资源及其资源名
        /// </summary>
        /// <param name="targetFilePath">要解包的资源文件。默认为当前目录下的"MyRes.pck"</param>
        /// <returns>资源字典，键值为资源唯一标示名。若无资源返回空集合。</returns>
        public static Dictionary<string,object> GetAllResources(string targetFilePath = "MyRes.pck")
        {
            Dictionary<string, object> rtn = new Dictionary<string, object>();
            using (ResourceReader rr = new ResourceReader(targetFilePath))
            {
                foreach (DictionaryEntry entry in rr)
                    rtn.Add(((string)entry.Key).Substring(1), entry.Value);
            }
            return rtn;
        }
        /// <summary>
        /// 根据资源名在指定的资源文件中检索资源
        /// </summary>
        /// <param name="resName">资源名</param>
        /// <param name="targetFilePath">要在其中检索的资源文件名，默认为"MyRes.pck"</param>
        /// <returns>资源名对应的资源</returns>
        public static object SearchResource(string resName,string targetFilePath="MyRes.pck")
        {
            object rtn=null;
            using (ResourceReader rr = new ResourceReader(targetFilePath))
            {
                foreach(DictionaryEntry entry in rr)
                    if ((string)entry.Key == '_' + resName)
                    {
                        rtn = entry.Value;
                        break;
                    }
            }
            return rtn;
        }
    }
}